SCRIPT_PATH = debug.getinfo(1).source:sub(debug.getinfo(1).source:find(".*\\")):sub(2)
dofile(SCRIPT_PATH .. "Common/AllClass.lua")

local active = true
local heros
local player = GetMyHero()

local function hasBladestorm()
    if lastUsed then
        if os.clock() - lastUsed > 3 then lastUsed = nil
        else
            return true, math.ceil(6 - ((os.clock() - lastUsed) * 2))
        end
    end
    return false, player:CanUseSpell(_E) == READY and 6 or 0
end

function OnTick()
    if active and (not lastUpdated or os.clock() - lastUpdated > 0.25) then
        lastUpdated = os.clock()

        if lastSpinTarget and (lastSpinTarget.dead or player:GetDistance(lastSpinTarget) > 330) then lastSpinTarget = nil end

        for i, target in ipairs(heros) do
            if target.visible and not target.dead and player:GetDistance(target) < 1200 then
                local qDmg = (player:GetSpellData(_Q).level < 1 or not player:CanUseSpell(_Q) == READY) and 0 or player:CalcDamage(target, (15 + (15 * player:GetSpellData(_Q).level)) + (player.totalDamage * 1.4))
                local bladestorm, remainingHits = hasBladestorm()
                local eDmg = player:GetSpellData(_E).level < 1 and 0 or remainingHits * player:CalcDamage(target, player.totalDamage * (.3 + player:GetSpellData(_E).level * .5) - 2.5 + player:GetSpellData(_E).level * 12.5)
                local rDmg = (player:GetSpellData(_R).level < 1 or not player:CanUseSpell(_R) == READY) and 0 or player:CalcMagicDamage(target,player:GetSpellData(_R).level * 175 + (target.maxHealth - target.health) / (4 - (player:GetSpellData(_R).level * 0.5)))

                if qDmg > 0 and qDmg + eDmg + rDmg > target.health and player:GetDistance(target) < 500 and player:CanUseSpell(_Q) == READY then
                    CastSpell(_Q)
                    player:Attack(target)
                end

                if eDmg > 0 and eDmg + rDmg > target.health and player:GetDistance(target) < 330 then
                    if player:CanUseSpell(_E) == READY then
                        if target.x and target.z then player:MoveTo(target.x, target.z) end
                        if remainingHits == 6 then CastSpell(_E) end
                        lastSpinTarget = target
                        return
                    elseif bladestorm and target.x and target.z then
                        player:MoveTo(target.x, target.z)
                        return
                    end
                else
                    lastSpinTarget = nil
                end
                if target.health < rDmg and player:GetDistance(target) < 400 and player:CanUseSpell(_R) == READY and not TargetHaveBuff({"spellshield","bansheesveil","undyingrage","judicatorintervention","nocturneshroudofdarkness"},target) then
                    CastSpell(_R, target)
                end
            end
        end
    end
end

function OnProcessSpell(object, spell)
    if player:CanUseSpell(_W) == READY and object.type == "obj_AI_Hero" and object.team == TEAM_ENEMY then
        if math.sqrt((player.x - spell.endPos.x) ^ 2 + (player.z - spell.endPos.z) ^ 2) < 100 then
            CastSpell(_W)
        end
    elseif object == player and spell.name == "GarenBladestorm" then
        lastUsed = os.clock()
    end
end

function OnWndMsg(msg, key)
    if key == 32 then
        if msg == KEY_DOWN then active = false
        else active = true
        end
    end
end

function OnLoad()
    if player.charName ~= "Garen" then
        PrintChat(" >> You are not playing as Garen. Unloading...")
        OnWndMsg, OnTick, OnProcessSpell = function() end, function() end, function() end
        return
    else
        heros = {}
        for i = 1, heroManager.iCount, 1 do
            local hero = heroManager:getHero(i)
            if hero.team ~= player.team then
                table.insert(heros, hero)
            end
        end
        PrintChat(" >> Garen Ultimate Helper loaded!")
    end
end
